<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use swoole_websocket_server;
use Swoole\WebSocket\Server;
class Swoole extends Command
{
    public $server;
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'swoole {action}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Active Push Message';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $arg = $this->argument('action');
        switch ($arg) {
            case 'start':
                $this->info('swoole server started');
                $this->start();
                break;
            case 'stop':
                $this->info('swoole server stoped');
                break;
            case 'restart':
                $this->info('swoole server restarted');
                break;
        }
    }

    /**
     * 启动Swoole
     */
    private function start()
    {
        $this->server = new swoole_websocket_server(env('SWOOLE_HOST'), env('SWOOLE_PORT'));
        //监听WebSocket连接打开事件
        $this->server->on('open', function (swoole_websocket_server $server, $request) {
            $this->info("server: handshake success with fd{$request->fd}\n");
        });
        //监听WebSocket消息事件
        $this->server->on('message', function (swoole_websocket_server $server, $frame) {
            $this->info("receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n");
            $server->push($frame->fd, "this is server");
        });
        //监听WebSocket连接关闭事件
        $this->server->on('close', function ($ser, $fd) {
            $this->info("client {$fd} closed\n");
        });
        //监听WebSocket主动推送消息事件
        $this->server->on('request', function ($request, $response) {
            // 接收http请求从get获取message参数的值，给用户推送
            // $this->server->connections 遍历所有websocket连接用户的fd，给所有用户推送
            foreach ($this->server->connections as $fd) {
                // 需要先判断是否是正确的websocket连接，否则有可能会push失败
                if ($this->server->isEstablished($fd)) {
                    $this->server->push($fd, $request->post['scene']);
                    $this->info("client is PushMessage\n".$request->post['scene']);
                }
            }
        });
        $this->server->start();
    }
}
